﻿using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEngine;

public partial class EditorFileHashUtil
{
	static string mDataPath;
	static string DataPath
	{
		get{
			
			if(mDataPath == null)
			{
				mDataPath = Application.dataPath + "/../EditorData";
				
				if(!Directory.Exists(mDataPath))
					Directory.CreateDirectory(mDataPath);
			}
			
			return mDataPath;
		}
	}
	

    static Dictionary<string,string> SaveFileHash(string dirPath,string saveName,bool saveFile = false)
    {
		Dictionary<string,string> mFileHash = new Dictionary<string,string>();
		
       string savePath = DataPath + "/" + saveName + ".txt";
	   
	   string[] files = Directory.GetFiles(dirPath,"*.*",SearchOption.AllDirectories);
	   
	   string lineStr="";
	   
	   int fnt = files.Length;
	   
	   for(int i = 0; i < fnt;i++)
	   {
			Hash128 hash128 =  AssetDatabase.GetAssetDependencyHash(files[i]);
			
			lineStr = GStringBuilder.Contact(lineStr,files[i],"|",hash128);
			
			if(i != fnt - 1)
				lineStr = GStringBuilder.Contact(lineStr,"\r\n");
	   }
	   
	   if(saveFile)
		File.WriteAllText(savePath,lineStr);
	   
	   return mFileHash;
    }
	
	static Dictionary<string,string> ReadFileHash(string fileName)
	{
		Dictionary<string,string> mFileHash = new Dictionary<string,string>();
		
		string savePath = DataPath + "/" + fileName + ".txt";
		
		if(!File.Exists(savePath))
			return mFileHash;
		
		string[] lines = File.ReadAllLines(savePath);
		
		int lnt = lines.Length;
		for(int i = 0; i < lnt;i++)
		{
			string[] pars = lines[i].Split('|');
			
			mFileHash.Add(pars[0],pars[1]);
		}
		
		return mFileHash;
	}
	
	static string lineStr;
	
	public static List<string> ChangeFile(string dirPath,string fileName,System.Action<string,float> call = null,bool checkDep = false,bool saveFile = false,string searchPat="*.*")
	{
        Dictionary<string, string> localHash = ReadFileHash(fileName);
		List<string> changeList = new List<string>();
		
		string tmpHash;
        bool haveChange = false;
		
		string savePath = DataPath + "/" + fileName + ".txt";
	   
		string[] files = Directory.GetFiles(dirPath, searchPat, SearchOption.AllDirectories);
	   
		lineStr="";
		
		int fnt = files.Length;
	   
		for(int i = 0; i < fnt;i++)
		{
            if (files[i].EndsWith(".meta")) continue;

            files[i] = files[i].Replace("\\", "/");

            Hash128 hash128 = AssetDatabase.GetAssetDependencyHash(files[i]);
			
			if(saveFile)
			{
				lineStr = GStringBuilder.Contact(lineStr,files[i],"|",hash128);
			
				if(i != fnt - 1)
					lineStr = GStringBuilder.Contact(lineStr,"\r\n");
			}
			
			string depLineStr = CheckDepItem(files[i],localHash);
			
			if(localHash.TryGetValue(files[i],out tmpHash) && tmpHash.ToString().CompareTo(hash128.ToString()) == 0)
				continue;

            haveChange = true;

            if (null != call)
			{
				float progress = (i+1)*1.0f/fnt*1.0f;
				call(files[i],progress);
			}	
		}
		
		if(saveFile)
			File.WriteAllText(savePath,lineStr);

        if (!haveChange)
            EditorUtility.DisplayDialog("提示", "文件没有改变", "确定");
		
		return changeList;
	}
	
	static string CheckDepItem(string path,Dictionary<string,string> localHash)
	{
		string tmpHash;
		string[] deps =  AssetDatabase.GetDependencies(path);
		int lnt = deps.Length;
		
		for(int i = 0; i < lnt;i++)
		{
            if (deps[i].CompareTo(path) == 0)
				continue;

            deps[i] = deps[i].Replace("\\", "/");

            if (deps[i].EndsWith(".meta")) continue;

            if (
            deps[i].EndsWith(".cs")
			|| deps[i].EndsWith(".shader")
			|| deps[i].EndsWith(".lua")
			)
			{
				continue;
			}
			
			Hash128 hash128 = AssetDatabase.GetAssetDependencyHash(deps[i]);
            lineStr = GStringBuilder.Contact(lineStr,deps[i], "|", hash128, "\r\n");
            
            if (localHash.TryGetValue(deps[i],out tmpHash) && tmpHash.ToString().CompareTo(hash128.ToString()) == 0)
				continue;
			
			CheckDepItem(deps[i],localHash);
		}
		
		return lineStr;
	}
}
